package sweep;

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;

class client_tmp {
    Socket client;
    String name;
    public client_tmp(Socket client, String name) {
        this.client = client;
        this.name = name;
    }
}

class ClientHandler implements Runnable {
    private final Socket server;
    private ArrayList<client_tmp> clients = new ArrayList<>();
    private int room_num = -1;
    String name;

    public ClientHandler(client_tmp m_client, ArrayList<client_tmp> clients) {
        this.server = m_client.client;
        this.clients = clients;
        name = m_client.name;
    }
    @Override
    public void run() {
        try {
            System.out.println("ClientHandler started!");
            DataInputStream in = new DataInputStream(server.getInputStream());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            while (true) {
                String msg = in.readUTF();
                String[] message = msg.split(" ");

                // 邀请另一名玩家
                if (message[0].equals("invite")) {
                    System.out.println("accept_invite_msg");
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    if (rival_index == -1) {
                        out.writeUTF("rival_unexist");
                        out.flush();
                    }
                    else {
                        DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                        rival_out.writeUTF("invite " + name);
                        rival_out.flush();
                    }
                }
                // 邀请接受
                else if (message[0].equals("invite_yes")) {
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                    rival_out.writeUTF("invite_yes " + message[2]);
                    rival_out.flush();
                }
                // 邀请拒绝
                else if (message[0].equals("invite_no")) {
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                    rival_out.writeUTF("invite_no");
                    rival_out.flush();
                }
                //游戏开始
                else if (message[0].equals("game_start")) {
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                    rival_out.writeUTF("game_start");
                    rival_out.flush();
                }
                // 其中一方游戏成功结束
                else if (message[0].equals("game_success")) {
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                    rival_out.writeUTF("fail");
                    System.out.println(rival + " fail");
                    rival_out.flush();
                }
                // 其中一方游戏失败结束
                else if (message[0].equals("game_fail")) {
                    String rival = message[1];
                    int rival_index = -1;
                    for (int i = 0; i < clients.size(); i++) {
                        if (clients.get(i).name.equals(rival)) {
                            rival_index = i;
                        }
                    }
                    DataOutputStream rival_out = new DataOutputStream(clients.get(rival_index).client.getOutputStream());
                    rival_out.writeUTF("success");
                    System.out.println(rival + " success");
                    rival_out.flush();
                }
                // 退出
                else if (message[0].equals("quit")) {
                    break;
                }
            }
            server.close();
        } catch (IOException e) {
            try {
                DataOutputStream out = new DataOutputStream(server.getOutputStream());
                out.writeUTF("OpponentLeave");
                out.flush();
            } catch (IOException e1) {
                System.out.println("Client " + server.getRemoteSocketAddress() + " disconnected!");
            }
        }
    }
}

public class Server {
    private final ServerSocket server;
    private ArrayList<client_tmp> clients = new ArrayList<>();

    private static DataOutputStream out;

    private int num = 0;

    public Server(int port) throws IOException {
        server = new ServerSocket(port);
    }
    public void run() {
        while (true) {
            try {
                System.out.println("Waiting for client on port " + server.getLocalPort() + "...");
                Socket server = this.server.accept();
                server.setSoTimeout(0);
                System.out.println("Just connected to " + server.getRemoteSocketAddress());
                String client_name = "player" + String.valueOf(num);
                num++;
                System.out.println("Client Name is: " + client_name);
                client_tmp client = new client_tmp(server, client_name);
                clients.add(client);
                try {
                    out = new DataOutputStream(server.getOutputStream());
                    out.writeUTF("num " + String.valueOf(num - 1));
                    for (int i = 0; i < clients.size(); i++) {
                        DataOutputStream every_out = new DataOutputStream(clients.get(i).client.getOutputStream());
                        every_out.writeUTF("all " + String.valueOf(num - 1));
                    }
                } catch (IOException ee) {
                    ee.printStackTrace();
                    return;
                }
                ClientHandler handler = new ClientHandler(client, clients);
                Thread t = new Thread(handler);
                t.start();
            } catch (SocketTimeoutException s) {
                System.out.println("Socket timed out!");
                break;
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }
    public static void main(String[] args) {
        try {
            Server test = new Server(8080);
            test.run();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
